Imports Clo = Enhancements.Core.Logging
Imports Ere = Enhancements.Basic.RegularExpressions
Imports Gen = System.Collections.Generic
Imports Glo = System.Globalization
Imports Iou = System.IO
Imports Pri = Enhancements.Basic.Primitives
Imports Ref = System.Reflection
Imports Reg = System.Text.RegularExpressions
Imports Sys = System
Imports Tex = System.Text
Imports Xsd = System.Xml.Schema
Imports W3c = System.Xml
Imports Vbn = Microsoft.VisualBasic

Namespace Enhancements.Basic.Expressions.Functions
    ''' <summary>Represents a token extracted from an expression that has a function parameters separator.</summary>
    <Serializable(), DebuggerStepThrough()> _
    Public NotInheritable Class FunctionParametersSeparator
        Inherits Token

        Private Sub New(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32, ByVal _expressionEndIndex As Sys.Int32)
            MyBase.New(_expression, _expressionBeginIndex, _expressionEndIndex)
        End Sub

        ''' <summary>The represention allowed for this type of token.</summary>
        Public Shared ReadOnly Property Representation() As String
            Get
                Dim _returnValue As System.String = ","

                Return _returnValue
            End Get
        End Property

        Private Shared Function __Parse(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32) As Sys.Object
            Dim _returnValue As Sys.Object = Nothing
            If _expression.IsNullNot("_expression", False) AndAlso _expression.IsEmptyNot("_expression", False) AndAlso _expressionBeginIndex.IsInRange("_expressionBeginIndex", 0, _expression.Length - 1, False) Then
                If ___Texts.StartsWith(_expression.Substring(_expressionBeginIndex), Representation) Then
                    _returnValue = New FunctionParametersSeparator(_expression, _expressionBeginIndex, _expressionBeginIndex + Representation.Length - 1)
                End If
            End If
            If Assert.IsNull(_returnValue, "_returnValue", False) Then
                _returnValue = FunctionParametersSeparatorParseException.___Create(_expression, _expressionBeginIndex)
            End If

            Return _returnValue
        End Function

        ''' <summary>Parses an expression for a function parameters separator starting by a begin index.</summary>
        ''' <param name="_expression">Expression to parse.</param>
        ''' <param name="_expressionBeginIndex">Expression begin index to use.</param>
        ''' <exception cref="FunctionParametersSeparatorParseException">The operation did not produce a valid token.</exception>
        ''' <returns> </returns>
        Public Overloads Shared Function Parse(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32) As FunctionParametersSeparator
            Dim _returnValue As Sys.Object = __Parse(_expression, _expressionBeginIndex)
            If Assert.IsOfType(_returnValue, "_returnValue", GetType(FunctionParametersSeparatorParseException), False) Then
                FunctionParametersSeparatorParseException.___Throw(CType(_returnValue, FunctionParametersSeparatorParseException))
            End If

            Return CType(_returnValue, FunctionParametersSeparator)
        End Function

        ''' <summary>Tries to parse an expression for a function parameters separator starting by a begin index.</summary>
        ''' <param name="_expression">Expression to parse.</param>
        ''' <param name="_expressionBeginIndex">Expression begin index to use.</param>
        ''' <param name="_result">The result of the operation if possible. If not, null is returned.</param>
        ''' <returns> </returns>
        Public Overloads Shared Function TryParse(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32, ByRef _result As FunctionParametersSeparator) As System.Boolean
            Dim _returnValue As System.Boolean = False
            Dim _dummy As Sys.Object = __Parse(_expression, _expressionBeginIndex)
            If Assert.IsOfType(_dummy, "_dummy", GetType(FunctionParametersSeparatorParseException), False) Then
                _result = Nothing
                _returnValue = False
            Else
                _result = CType(_dummy, FunctionParametersSeparator)
                _returnValue = True
            End If

            Return _returnValue
        End Function

        ''' <summary>Determines the token's correct representation for use in an expression.</summary>
        ''' <returns> </returns>
        Public Overrides Function ToRepresentation() As System.String
            Dim _returnValue As System.String = Representation

            Return _returnValue
        End Function

        ''' <exception cref="IsNullException"> </exception>
        ''' <exception cref="IsListFilledNotException"> </exception>
        Friend Shared Function ___ParseAll(ByRef _tokens As Gen.List(Of Token)) As Sys.Int32
            _tokens.IsListFilled("_tokens", True)

            Dim _returnValue As Sys.Int32 = 0
            Dim _tokensNew As Gen.List(Of Token) = New Gen.List(Of Token)()
            For _counter1 As Sys.Int32 = 0 To _tokens.Count - 1
                If _tokens(_counter1).IsOfType("_tokens(_counter1)", GetType(Undetermined), False) Then
                    Dim _tokensToken As Undetermined = CType(_tokens(_counter1), Undetermined)
                    For _counter2 As Sys.Int32 = 0 To _tokensToken.ExpressionPart.Length - 1
                        Dim _functionParametersSeparator As FunctionParametersSeparator = Nothing
                        If TryParse(_tokensToken.Expression, _tokensToken.ExpressionBeginIndex + _counter2, _functionParametersSeparator) Then
                            _tokensNew.Add(_functionParametersSeparator)
                            _counter2 += _functionParametersSeparator.ExpressionPart.Length - 1
                            _returnValue += 1
                        Else
                            Undetermined.___AppendNewToEndOrReplaceLastWithNew(_tokensNew, _tokensToken.Expression, _tokensToken.ExpressionBeginIndex + _counter2, _tokensToken.ExpressionBeginIndex + _counter2)
                        End If
                    Next _counter2
                Else
                    _tokensNew.Add(_tokens(_counter1))
                End If
            Next _counter1
            _tokens = _tokensNew

            Return _returnValue
        End Function

        ''' <exception cref="IsNullException"> </exception>
        ''' <exception cref="IsListFilledNotException"> </exception>
        ''' <exception cref="IsInRangeNotException"> </exception>
        ''' <exception cref="CompilerExpressionSubexpressionStartsWithFunctionParametersSeparatorException"> </exception>
        ''' <exception cref="CompilerExpressionSubexpressionEndsWithFunctionParametersSeparatorException"> </exception>
        ''' <exception cref="CompilerExpressionSubexpressionContainsAdjacentFunctionParametersSeparatorsException"> </exception>
        Friend Shared Function ___AssertAndFindFunctionSubexpressionsOccurrences(ByVal _expression As System.String, ByVal _tokens As Gen.List(Of Token), ByVal _beginTokenIndex As Sys.Int32, ByVal _endTokenIndex As Sys.Int32) As Pri.Occurrence()
            _tokens.IsListFilled("_tokens", True)
            _beginTokenIndex.IsInRange("_beginTokenIndex", 0, Sys.Int32.MaxValue, True)
            _endTokenIndex.IsInRange("_endTokenIndex", 0, Sys.Int32.MaxValue, True)

            Dim _returnValueList As Gen.List(Of Pri.Occurrence) = New Gen.List(Of Pri.Occurrence)()
            If _beginTokenIndex.IsInRange("_beginTokenIndex", 0, _tokens.Count - 1, False) Then
                If _endTokenIndex.IsInRange("_endTokenIndex", _beginTokenIndex, _tokens.Count - 1, False) Then
                    Dim _symbolicalCharacterForOwn As System.Char = ","c
                    Dim _symbolicalCharacterForOther As System.Char = "?"c
                    Dim _symbolicalString As System.String = Sys.String.Empty
                    For _counter As Sys.Int32 = _beginTokenIndex To _endTokenIndex
                        If _tokens(_counter).IsOfType("_tokens(_counter)", GetType(FunctionParametersSeparator), False) Then
                            _symbolicalString += _symbolicalCharacterForOwn
                        Else
                            _symbolicalString += _symbolicalCharacterForOther
                        End If
                    Next _counter
                    If ___Texts.StartsWith(_symbolicalString, _symbolicalCharacterForOwn).IsTrue("___Texts.StartsWith(_symbolicalString, _symbolicalCharacterForOwn)", False) Then
                        CompilerExpressionSubexpressionStartsWithFunctionParametersSeparatorException.___Throw(_expression, _tokens.GetRange(_beginTokenIndex, _endTokenIndex - _beginTokenIndex + 1).ToArray())
                    End If
                    If ___Texts.EndsWith(_symbolicalString, _symbolicalCharacterForOwn).IsTrue("___Texts.EndsWith(_symbolicalString, _symbolicalCharacterForOwn)", False) Then
                        CompilerExpressionSubexpressionEndsWithFunctionParametersSeparatorException.___Throw(_expression, _tokens.GetRange(_beginTokenIndex, _endTokenIndex - _beginTokenIndex + 1).ToArray())
                    End If
                    If Pri.String.FindOccurrences(_symbolicalString, _symbolicalCharacterForOwn + _symbolicalCharacterForOwn).Length.IsInRange("Pri.String.FindOccurrences(_symbolicalString, _symbolicalCharacterForOwn + _symbolicalCharacterForOwn).Length", 1, Sys.Int32.MaxValue, False) Then
                        CompilerExpressionSubexpressionContainsAdjacentFunctionParametersSeparatorsException.___Throw(_expression, _tokens.GetRange(_beginTokenIndex, _endTokenIndex - _beginTokenIndex + 1).ToArray())
                    End If
                    Dim _previousTokenIsFunctionParametersSeparator As System.Boolean = True
                    Dim _currentParameterBeginTokenIndex As Sys.Int32 = -1
                    Dim _currentParameterEndTokenIndex As Sys.Int32 = -1
                    For _counter As Sys.Int32 = _beginTokenIndex To _endTokenIndex
                        If (_symbolicalString.Chars(_counter - _beginTokenIndex) = _symbolicalCharacterForOther).IsTrue("_symbolicalString.Chars(_counter - _beginTokenIndex) = _symbolicalCharacterForOther", False) Then
                            If _previousTokenIsFunctionParametersSeparator.IsTrue("_previousTokenIsFunctionParametersSeparator", False) Then
                                _currentParameterBeginTokenIndex = _counter
                                _currentParameterEndTokenIndex = _counter
                            Else
                                _currentParameterEndTokenIndex = _counter
                            End If
                            _previousTokenIsFunctionParametersSeparator = False
                        Else
                            _returnValueList.Add(New Pri.Occurrence(_currentParameterBeginTokenIndex, _currentParameterEndTokenIndex))
                            _previousTokenIsFunctionParametersSeparator = True
                        End If
                        If _counter.IsInRange("_counter", _endTokenIndex, _endTokenIndex, False) Then
                            _returnValueList.Add(New Pri.Occurrence(_currentParameterBeginTokenIndex, _currentParameterEndTokenIndex))
                        End If
                    Next _counter
                End If
            End If

            Return _returnValueList.ToArray()
        End Function

    End Class
End Namespace
